/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Mesh.h"


#include <线性代数/矢量计算.h>
#include <矩阵计算.h>


#include "core/几何计算/vec_array.h"
#include "core/shader_mesh.h"
#include "core/shader_line.h"
#include "core/mesh_container.h"
#include "core/shader_taster_transform.h"
#include "core/空间划分/球形八叉树.h"

#include "面/几何模型生成.h"


#include "底层绘图/底层绘图框架.h"

#include <几何图形/图形相交.h>





void S_Mesh::f_创建板载缓存族(E_绘图API engineType) {
	if (m_板载缓存族 != engineType) {
		f_clear板载缓存();
	}

	m_板载缓存族 = engineType;

}

void f_me_set多维材质(S_Mesh* me, S_材质管线* 材质, uint32 元素索引, uint32 槽) {
	if (槽 < me->m_多维材质数量 && 元素索引 < me->m_元素->m_多维元素数量) {
		me->m_多维材质槽[槽].m_Material = 材质;
		me->m_多维材质槽[槽].m_区间槽索引 = 元素索引;
	}
}

void f_me_分配光追几何(S_Mesh* me) {
	static uint32 加速结构交叉分配 = 0;
	if (加速结构交叉分配 & 1) {
		me->m_底层光追加速结构 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		(*me->m_底层光追加速结构) = f_bm_alloc(f_buf_getGlobal().g_BLAS_0, 0);
	}
	else {
		me->m_底层光追加速结构 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		(*me->m_底层光追加速结构) = f_bm_alloc(f_buf_getGlobal().g_BLAS_1, 0);
	}

	me->m_光追网格ID = me->m_网格属性->m_Mem.m_偏移;
	++加速结构交叉分配;
}

void f_me_alloc多维材质槽(S_Mesh* me, uint32 num, S_材质管线* 默认材质) {
	if (me->m_多维材质数量 != num) {
		f_me_free多维材质槽(me);

		me->m_多维材质数量 = num;
		me->m_多维材质槽 = (S_管线槽*)calloc(me->m_多维材质数量, sizeof(S_管线槽));
	}

	for (uint32 i = 0; i < num; ++i) {
		me->m_多维材质槽[i].m_Material = 默认材质;
		me->m_多维材质槽[i].m_区间槽索引 = 0;
	}
}

void f_me_init材质槽(S_管线槽* 材质槽, uint32 num) {
	for (uint32 i = 0; i < num; ++i) {
		材质槽[i].m_参数槽 = {};
	}
}

void f_me_alloc多维材质槽(S_Mesh* me, uvec2* 索引区间, uint32 num, S_材质管线* 默认材质) {
	if (me->m_多维材质数量 != num) {
		f_me_free多维材质槽(me);

		me->m_多维材质数量 = num;
		me->m_多维材质槽 = (S_管线槽*)calloc(me->m_多维材质数量, sizeof(S_管线槽));
		
		f_me_init材质槽(me->m_多维材质槽, num);
	}

	for (uint32 i = 0; i < num; ++i) {
		me->m_多维材质槽[i].m_Material = 默认材质;
		me->m_多维材质槽[i].m_区间槽索引 = 0;
	}
}

void f_me_free多维材质槽(S_Mesh* me) {
	if(me->m_多维材质槽) {
		free(me->m_多维材质槽);
	}
}

void f_me_free多维元素槽(S_Mesh* me) {
	if (me->m_元素->m_元素区间) {
		free(me->m_元素->m_元素区间);
	}
	free(me->m_元素);
}


int8 f_顶点配置标志(S_Mesh* mesh, E_顶点标志位 type) {
	for (uint8 i = 0; i < 4; ++i) {
		if (((*mesh->m_顶点配置Flags << (i*4))&0x0000000f) == type) {
			return i;
		}
	}
	return -1;
}

void f_mesh_创建骨骼(S_Mesh* mesh, S_设备环境& ctx) {
}

void f_mesh_创建颜色缓存(S_Mesh* mesh, S_设备环境& ctx) {
}




void f_surface_变换顶点(S_Mesh* mesh, const Mat44f& mat, const vec3& 缩放, const vec3& 偏移, std::vector<vec3>& 点) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;

	点.resize(num);

	switch (*mesh->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* v = f_buf_VNT_ptr(*mesh->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				auto a = (mat * v[i].vert);
				auto b = (a + 偏移);
				auto c = b * 缩放;
				点[i] = (a + 偏移) * 缩放;
			}
			break;
		}
		default:
			break;
	}
}




